package edu.mapi.ir.planning;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.util.Vector;

import edu.mapi.ir.viewer.IMapLayer;
import edu.mapi.ir.viewer.Maze;
/**
 * @author ZP
 */
public class SimpleMap implements IMapLayer {

	protected Boolean[][] obstacles;
	protected int width, height;	
	protected Maze maze;
	protected Vector<Point2D> currentPath = null;
	
	public SimpleMap(Maze maze) {
		this.maze = maze;
		width = (int)Math.ceil(maze.getWidth());
		height = (int)Math.ceil(maze.getHeight());
		obstacles = new Boolean[width][height];
		
		Area obsArea = maze.getObstacleArea();
		
		for (int i = 0; i < width; i++) {
			for (int j = 0; j < height; j++) {
				
				// verify if a circle with diameter=1 fits inside the cell
				Area circle = new Area(new Ellipse2D.Double(i,j,1,1));
				Area dummy = (Area)obsArea.clone();
				dummy.intersect(circle);
								
				if (!dummy.isEmpty()) 
					obstacles[i][j] = true;
				else
					obstacles[i][j] = false;
			}
		}		
	}
	
	public BufferedImage getLayerImage(double zoom) {
		BufferedImage img = new BufferedImage((int)(zoom * width), (int)(zoom * height), BufferedImage.TYPE_INT_ARGB);
		Graphics2D g2d = (Graphics2D) img.getGraphics();
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		
		//g2d.translate(0, height * zoom - zoom);
		g2d.setColor(new Color(0,255,0,100));
		
		for (int i = 0; i < maze.getWidth(); i++) {			
			for (int j = 0; j < maze.getHeight(); j++) {				
				if (obstacles[i][j]) {
					RoundRectangle2D.Double r = new RoundRectangle2D.Double(i*zoom,(maze.getHeight()-j-1)*zoom,zoom,zoom, zoom/3, zoom/3);
					g2d.setColor(new Color(0,255,50,100));
					g2d.fill(r);
					g2d.setColor(new Color(0,100,50));
					g2d.draw(r);
				}
			}
		}

		if (currentPath != null) {
			if (currentPath.size() <= 1)
				return img;
			Point2D lastPt =  currentPath.firstElement();
			
			for (int i = 1; i < currentPath.size(); i++) {
				Point2D pt = currentPath.get(i);
				g2d.setColor(Color.red);
				g2d.draw(new Line2D.Double((lastPt.getX())*zoom, (maze.getHeight()-lastPt.getY())*zoom, 
					(pt.getX())*zoom, (maze.getHeight()-pt.getY())*zoom));
				g2d.setColor(Color.yellow);				
				g2d.fill(new Ellipse2D.Double((pt.getX())*zoom-2, (maze.getHeight()-pt.getY())*zoom-2, 4, 4));
				lastPt = pt;
			}						
		}
		
		return img;
	}
	
	public boolean hasLayerChanged() {
		return false;
	}

	public Vector<Point2D> getCurrentPath() {
		return currentPath;
	}

	public void setCurrentPath(Vector<Point2D> currentPath) {
		this.currentPath = currentPath;
	}

	public Maze getMaze() {
		return maze;
	}

	public void setMaze(Maze maze) {
		this.maze = maze;
	}
	
	public boolean isObstacle(int i, int j) {
		return obstacles[i][j];
	}
	
}
